package com.wmzdq.security;

import java.io.IOException;
import java.util.List;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.SecurityMetadataSource;
import org.springframework.security.access.intercept.AbstractSecurityInterceptor;
import org.springframework.security.access.intercept.InterceptorStatusToken;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.authentication.logout.LogoutHandler;

import com.alibaba.fastjson.JSON;
import com.wmzdq.framework.BaseResponse;
import com.wmzdq.framework.constant.Constants;
import com.wmzdq.framework.constant.ErrorCode;



//权限验证 过滤器
public class SecurityFilter extends AbstractSecurityInterceptor implements Filter {
    
    private FilterInvocationSecurityMetadataSource securityMetadataSource;
    
    private List<LogoutHandler> handlers;
    
    @Override
    public SecurityMetadataSource obtainSecurityMetadataSource() {
        return this.securityMetadataSource;
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		FilterInvocation fi = new FilterInvocation(request, response, chain);
		invoke(fi);
    }

    private void invoke(FilterInvocation fi) throws IOException, ServletException {
    	InterceptorStatusToken token = super.beforeInvocation(fi);
    	if(token == null){
    		String requestType = fi.getRequest().getHeader("X-Requested-With");
    		if("XMLHttpRequest".equals(requestType)){
    			BaseResponse baseResponse = new BaseResponse();
        		baseResponse.setCode(ErrorCode.SECURITY_ERROR);
        		baseResponse.setMessage("访问的页面不存在或没有此页面权限");
        		
        		HttpServletResponse response = fi.getResponse();
        		response.getWriter().print(JSON.toJSONString(baseResponse));
        		response.addHeader("Content-Type", "application/json");
    			return;
    			
    			//response.setHeader("sessionstatus", "timeout");//在响应头设置session状态  
                //return ; 
    		}else{
    			fi.getRequest().getSession().setAttribute(Constants.ERROR_MSG, "访问的页面不存在或没有此页面权限");
    			throw new AccessDeniedException("访问的页面不存在 ");
    		}
    	}
        try {
            fi.getChain().doFilter(fi.getRequest(), fi.getResponse());
        }
        finally {
            super.afterInvocation(token, null);
        }
    }

    public FilterInvocationSecurityMetadataSource getSecurityMetadataSource() {
        return securityMetadataSource;
    }

    public void setSecurityMetadataSource(FilterInvocationSecurityMetadataSource securityMetadataSource) {
        this.securityMetadataSource = securityMetadataSource;
    }

    public void init(FilterConfig config) throws ServletException {
        // TODO Auto-generated method stub
    }

    public void destroy() {
        // TODO Auto-generated method stub

    }

    public void setHandlers(List<LogoutHandler> handlers) {
		this.handlers = handlers;
	}

	@Override
    public Class<? extends Object> getSecureObjectClass() {
        // 下面的MyAccessDecisionManager的supports方面必须放回true,否则会提醒类型错误
        return FilterInvocation.class;
    }
	
	/*private void ForceRedirect(HttpServletRequest request, HttpServletResponse response){
		String uri = request.getRequestURI();
		String url = request.getRequestURL().toString();
		System.out.println("schema="+request.getScheme());
		if("/admin/vendor/info/page/create".equals(uri) && url.indexOf("https") > 0){
			String redirectUrl = "http://" + request.getServerName() + uri;
			try {
				response.sendRedirect(redirectUrl);
			} catch (IOException e) {
				e.printStackTrace();
			}
			return;
		}
	}*/
}